#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <stdint.h>

// 配置串口参数
int configure_serial(int fd, int baudrate) {
    struct termios options;
    
    // 获取当前配置
    if (tcgetattr(fd, &options) != 0) {
        perror("tcgetattr");
        return -1;
    }
    
    // 设置波特率
    speed_t speed;
    switch (baudrate) {
        case 9600:   speed = B9600; break;
        case 19200:  speed = B19200; break;
        case 38400:  speed = B38400; break;
        case 57600:  speed = B57600; break;
        case 115200: speed = B115200; break;
        case 921600: speed = B921600; break;
        default:     speed = B9600; break;
    }
    
    cfsetispeed(&options, speed);
    cfsetospeed(&options, speed);
    
    // 8位数据位，无校验，1位停止位
    options.c_cflag &= ~PARENB;   // 无校验
    options.c_cflag &= ~CSTOPB;   // 1位停止位
    options.c_cflag &= ~CSIZE;    // 清除数据位设置
    options.c_cflag |= CS8;       // 8位数据位
    options.c_cflag |= CREAD | CLOCAL; // 启用接收，忽略调制解调器状态线
    
    // 原始模式
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    options.c_iflag &= ~(IXON | IXOFF | IXANY);
    options.c_iflag &= ~(INLCR | IGNCR | ICRNL);
    options.c_oflag &= ~OPOST;
    
    // 设置超时
    options.c_cc[VTIME] = 10; // 1秒超时
    options.c_cc[VMIN] = 0;
    
    // 应用配置
    if (tcsetattr(fd, TCSANOW, &options) != 0) {
        perror("tcsetattr");
        return -1;
    }
    
    return 0;
}

int main(int argc, char *argv[]) {
    int fd;
    const char *device = "/dev/ttyS2";  // 默认设备
    int baudrate = 9600;                // 默认波特率

    // 解析命令行参数
    if (argc > 1) {
        device = argv[1];
    }
    if (argc > 2) {
        baudrate = atoi(argv[2]);
    }
    
    printf("Device: %s, Baudrate: %d\n", device, baudrate);
    
    // 打开串口设备
    fd = open(device, O_RDWR | O_NOCTTY);
    if (fd < 0) {
        perror("Failed to open device");
        return -1;
    }
    
    // 配置串口
    if (configure_serial(fd, baudrate) < 0) {
        close(fd);
        return -1;
    }
    
    printf("Serial port configured successfully\n");
    printf("Sending command: FF 03 00 01 00 02 80 15\n");
    printf("Press Ctrl+C to exit\n\n");
    
    // 要发送的固定指令
    uint8_t command[] = {0xFF, 0x03, 0x00, 0x01, 0x00, 0x02, 0x80, 0x15};
    uint8_t response[64];  // 接收缓冲区
    int bytes_written, bytes_read;
    int counter = 0;
    
    while (1) {
        counter++;
        
        // 清空输入缓冲区
        tcflush(fd, TCIFLUSH);
        
        // 发送指令
        bytes_written = write(fd, command, 8);
        if (bytes_written != 8) {
            printf("Write failed, expected 8 bytes, actual %d bytes\n", bytes_written);
            continue;
        }
        
        printf("Read #%d\n", counter);
        printf("TX: ");
        for (int i = 0; i < 8; i++) {
            printf("%02X ", command[i]);
        }
        printf("\n");
        
        // 等待响应
        usleep(50000); // 50ms延时
        
        // 接收响应
        bytes_read = read(fd, response, sizeof(response));
        
        if (bytes_read > 0) {
            printf("RX (%d bytes): ", bytes_read);
            for (int i = 0; i < bytes_read; i++) {
                printf("%02X ", response[i]);
            }
            printf("\n");
            
            // 简单分析响应数据
            if (bytes_read >= 3) {
                printf("Analysis: Slave=0x%02X, Function=0x%02X, Data_Count=%d\n", 
                       response[0], response[1], response[2]);
                
                if (bytes_read >= 7 && response[1] == 0x03) {
                    // 标准Modbus读寄存器响应格式分析
                    printf("Data: ");
                    for (int i = 3; i < bytes_read - 2; i++) {
                        printf("%02X ", response[i]);
                    }
                    printf("\n");
                    
                    // 如果是4字节数据，解析为32位数值（低16位在前，高16位在后）
                    if (response[2] == 4) {
                        // 修正：低16位在前，高16位在后
                        uint16_t low16 = ((uint16_t)response[3] << 8) | response[4];   // 前两个字节是低16位
                        uint16_t high16 = ((uint16_t)response[5] << 8) | response[6];  // 后两个字节是高16位
                        
                        // 32位值：高16位 << 16 + 低16位
                        uint32_t value = ((uint32_t)high16 << 16) | low16;
                        
                        printf("32-bit value: 0x%08X (%u)\n", value, value);
                        printf("High 16-bit: 0x%04X (%u), Low 16-bit: 0x%04X (%u)\n", 
                               high16, high16, low16, low16);
                    }
                    
                    if (bytes_read >= 7) {
                        printf("CRC: %02X %02X\n", response[bytes_read-2], response[bytes_read-1]);
                    }
                }
            }
        } else {
            printf("RX: No response received (timeout or error)\n");
        }
        
        printf("\n");
        
        // 间隔时间可调整 - 试试更短的间隔看数据变化
        usleep(100000); // 100ms间隔，观察数据是否连续变化
    }
    
    close(fd);
    return 0;
}